<template>
    <van-popup v-model="personShow"
        position="right"
        :style="{ height: '100%', width: '80%' }">
        <div class="user-box">
            <header>
                <input type="text" v-model="personQuery.name" placeholder="输入用户姓名">
                <button @click="pickPerson(true)">查询</button>
            </header>
            <ul @scroll="scrollEvt">
                <li v-for="item in personList"
                    @click="pickUser(item)"
                    :key="item.id">
                    {{item.name}} {{item.dept}} {{item.duties}}
                </li>
                <li class="more">
                    {{
                        loading ? '加载中...' : hasMore ? '上滑加载更多' : '不要滑了，没有了'
                    }}
                </li>
            </ul>
        </div>
    </van-popup>
</template>

<script>
    import { personListApi } from '../apis/projectApi'

    export default {

        props: {
            // [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. 
            // Instead, use a data or computed property based on the prop's value. Prop being mutated: "personShow"
            // prop值只能只读，不能修改props值
            // personShow: {
            value: {
                type: Boolean,
                default: false
            }
        },

        // 因为是一个组件，所以需要在页面展开的时候，来执行数据调用方法
        watch: {
            // personShow(val) {
            value(val) {
                if (val) {
                    this.pickPerson()
                    this.personShow = true
                }
            },

            // 当弹出框关闭的时候，需要修改组件的props值
            personShow(val) {
                if (!val) {
                    this.$emit('input', false)
                }
            }
        },

        data() {
            return {
                personShow: false,
                personList: [],
                // 查询用户信息的查询对象
                personQuery: {
                    name: '',
                    page: 1,
                    size: 20
                },
                // 分页需要这样几个条件: 再加载数据的时候，不能进行下一页数据；一定要滚动到底部；后端还有数据没有获取回来
                loading: false,
                hasMore: true
            }
        },
        
        methods: {
            pickPerson(isQuery) {
                // 需要把查询条件重置为空
                this.personQuery.page = 1
                this.personList = []

                // 加载状态开启
                this.loading = true

                // 发起数据请求
                this.getPersonList()
                // 在执行查询的时候不能调用
                if (!isQuery) {
                    this.personQuery.name = ''
                    this.personShow = true
                }
            },

            // getPersonList 获取用户数据的方法
            async getPersonList() {
                let result = await personListApi(this.personQuery)
                if (result.code === 200) {
                    this.personList = this.personList.concat(result.data.rows)

                    // 计算是否还有数据没有从后端获取回来: 当前页面 * 每一页数据 一定要小于 总数据
                    this.hasMore = this.personQuery.page * this.personQuery.size < result.data.total
                }

                // 因为vue是虚拟dom，而虚拟dom更新和赋值是异步，所以再关闭加载状态时，需要延迟
                setTimeout(() => {
                    this.loading = false
                })
            },

            // 滚动加载 -- 谁是容器(ul)，来注册滚动事件
            scrollEvt() {
                let target = window.event.target

                // 计算是否已经滚动到底部：容器展示高度 + 已经滚动上去的距离 === 容器的真实高度
                let isBottom = (target.clientHeight + target.scrollTop + 20) > target.scrollHeight

                // 因为要做请求节流(第一次请求没有结束的情况下，不能发起第二次请求)，必须有更多数据，一定要滚动到底部的时候才能执行加载
                if (!this.loading && this.hasMore && isBottom) {
                    // 开启节流阀门
                    this.loading = true

                    this.personQuery.page += 1
                    this.getPersonList()
                }
            },

            // 选择具体的负责人 -- 因为我们是一个独立的组件，所以应该把数据传递出去给父组件
            pickUser(user) {
                this.$emit('userPickEvt', user)

                this.personShow = false
            }
        }
    }
</script>


<style lang="less" scoped>
    @import '../style/common.less';

    .user-box {
        display: block;
        height: 100%;
        > header {
            display: flex;
            padding: 8px 12px;
            border-bottom: solid 1px @cdd;
            input {
                flex: 1;
                padding: 0;
                outline: none;
                border: none;
                font-size: .7rem;
                color: @c33;
                line-height: 32px;
            }
            button {
                flex: 0 0 68px;
                height: 32px;
                background-color: @primary;
                border: none;
                color: @cff;
                font-size: .7rem;
            }
        }

        > ul {
            display: block;
            padding: 8px 12px;
            height: calc(100% - 49px);
            overflow-x: hidden;
            li {
                border-bottom: solid 1px #ddd;
                font-size: .7rem;
                padding: 10px;
                &:last-child {
                    border-bottom: none;
                }
                &.more {
                    text-align: center;
                    color: @c99;
                }
            }
        }
    }
</style>